import { defineStore } from "pinia";
import type { Ref } from 'vue'
import type { RouteLocationNormalized } from "vue-router";

export interface TagView extends Partial<RouteLocationNormalized> {
  title?: string;
}

interface TagsViewState {
  visitedViews: Ref<TagView[]>;
  cachedViews: Ref<string[]>;
  addVisitedView: (view: TagView) => void;
  addCachedView: (view: TagView) => void;
  delVisitedView: (view: TagView) => TagView[];
  delCachedView: (view: TagView) => string[];
  addView: (view: TagView) => void;
  delView: (view: TagView) => void;
}

export const useTagsViewStore = defineStore("tagsView", (): TagsViewState => {
  // state
  const visitedViews = ref<TagView[]>([]);
  const cachedViews = ref<string[]>([]);

  // actions
  function addVisitedView(view: TagView) {
    if (visitedViews.value.some((v) => v.path === view.path)) return;
    if (view.meta && view.meta.affix) {
      visitedViews.value.unshift(
        Object.assign({}, view, {
          title: view.meta?.title || "no-name",
        })
      )
    } else {
      visitedViews.value.push(
        Object.assign({}, view, {
          title: view.meta?.title || "no-name",
        })
      )
    }
  }

  function addCachedView(view: TagView) {
    const viewName = view.name as string;
    if (cachedViews.value.includes(viewName)) return;
    if (view.meta?.keepAlive) {
      cachedViews.value.push(viewName);
    }
  }

  function delVisitedView(view: TagView) {
    for (const [i, v] of visitedViews.value.entries()) {
      if (v.path === view.path) {
        visitedViews.value.splice(i, 1);
        break;
      }
    }
    return [...visitedViews.value];
  }

  function delCachedView(view: TagView) {
    const viewName = view.name as string;
    const index = cachedViews.value.findIndex((v) => (v == viewName));
    index > -1 && cachedViews.value.splice(index, 1)
    return [...cachedViews.value];
  }

  function addView(view: TagView) {
    addVisitedView(view);
    addCachedView(view);
  }

  function delView(view: TagView) {
    delVisitedView(view);
    delCachedView(view);
  }


  return {
    visitedViews,
    cachedViews,
    addVisitedView,
    addCachedView,
    delVisitedView,
    delCachedView,
    addView,
    delView,
  }
})